#include <xscript/xabstractsyntaxtree.h>
#include <xscript/xabstractsyntaxtreevisitor.h>
#include <xscript/xscriptexecutor.h>
#include <xscript/xvariabletable.h>
#include <xscript/xitemundefined.h>
#include <astree/xabstractsyntaxtreearithmetic.h>

XAbstractSyntaxTreePtr XAbstractSyntaxTree::createFromToken(XTokenPtr token) {
    if (!token->asPunctuator())
        return nullptr;

    if (token->getString() == L"+")
        return std::make_shared<XAbstractSyntaxTreePlus>(token);
    else if (token->getString() == L"-")
        return std::make_shared<XAbstractSyntaxTreeMinus>(token);
    else if (token->getString() == L"*")
        return std::make_shared<XAbstractSyntaxTreeMulti>(token);
    else if (token->getString() == L"/")
        return std::make_shared<XAbstractSyntaxTreeDiv>(token);
    return nullptr;
}

XAbstractSyntaxTree::XAbstractSyntaxTree(XTokenPtr inputToken):
    token(inputToken) {
    result = std::make_shared<XItemUndefined>();
}

void XAbstractSyntaxTree::accept(std::shared_ptr<XAbstractSyntaxTreeVisitor> visitor) {
    if (visitor) {
        visitor->visit(std::dynamic_pointer_cast<XAbstractSyntaxTree>(shared_from_this()));
        for (auto& child : children)
            visitor->visit(std::dynamic_pointer_cast<XAbstractSyntaxTree>(child->shared_from_this()));
    }
}

bool XAbstractSyntaxTree::swtichVariableTable(std::shared_ptr<XVariableTable> table, const std::wstring& module, uint32_t block) {
    if (!table->setCurrentModule(module)) {
        XScriptExecutor::getInstance()->setError(XError::XError_BadModuleNameError, module);
        return false;
    }

    if (!table->setCurrentBlock(block)) {
        XScriptExecutor::getInstance()->setError(XError::XError_BadBlockError, std::to_wstring(block));
        return false;
    }

    return true;
}
